namespace Gj.Cache
{
    public class LRUDoubleLinkedList<K, V>
    {
        private readonly LRUNode<K, V> Head;
        private readonly LRUNode<K, V> Tail;

        public LRUDoubleLinkedList()
        {
            Head = new LRUNode<K, V>();
            Tail = new LRUNode<K, V>();
            Head.Next = Tail;
            Tail.Previous = Head;
        }

        public void AddToTop(LRUNode<K, V> node)
        {
            node.Next = Head.Next;
            Head.Next.Previous = node;
            node.Previous = Head;
            Head.Next = node;
        }

        public void RemoveNode(LRUNode<K, V> node)
        {
            node.Previous.Next = node.Next;
            node.Next.Previous = node.Previous;
            node.Next = null;
            node.Previous = null;
        }

        public LRUNode<K, V> RemoveLRUNode()
        {
            var target = Tail.Previous;
            RemoveNode(target);
            return target;
        }
    }
}